﻿using Microsoft.AspNetCore.Http;
using Microsoft.EntityFrameworkCore;
using System;
using System.ComponentModel.DataAnnotations;
using System.Threading.Tasks;
using System.Linq;
namespace server03_orm
{
    class Program
    {
        static void Main(string[] args)
        {
            var server = new light.http.server.httpserver();
            server.SetFailAction(on404);
            server.SetHttpAction("/dbinit", onDbInit);
            server.SetHttpAction("/dbwrite", onDbWrite);
            server.SetHttpAction("/dbread", onDbRead);
            server.Start(1988);
            Console.WriteLine("server on:1988");
            while (true)
            {
                Console.ReadLine();
            }
        }
        static async Task on404(HttpContext context)
        {
            await context.Response.WriteAsync("you got a 404");
        }
        static MyDbObj dbobj = null;
        static bool isLock
        {
            get
            {
                lock (_lock)
                {
                    return btag;
                }
            }
        }
        static void SetLockTag()
        {
            lock (_lock)
            {
                btag = true;
            }
        }
        static void ClearLockTag()
        {
            lock (_lock)
            {
                btag = false;
            }
        }
        static bool btag = false;
        static object _lock = new object();
        static async Task<bool> SafeInitDb()
        {
            try
            {
                while (isLock)
                {
                    await Task.Delay(100);
                }
                lock (_lock)
                {
                    if (dbobj != null)
                        return true;
                    SetLockTag();
                    dbobj = new MyDbObj();
                }
                await dbobj.Database.EnsureCreatedAsync();
                ClearLockTag();
                return true;

            }
            catch
            {
                return false;
            }
        }
        static async Task onDbInit(HttpContext context)
        {
            bool b = await SafeInitDb();
            if (!b)
            {
                await context.Response.WriteAsync("you got a onDbInit error");
                return;
            }
            await context.Response.WriteAsync("you got a onDbInit");

        }
        static async Task onDbWrite(HttpContext context)
        {
            await SafeInitDb();
            dbobj.items.Add(new Item1() { name = "abc", count = 4 });
            await dbobj.SaveChangesAsync();
        }
        static async Task onDbRead(HttpContext context)
        {
            await SafeInitDb();
            //这个不会真的触发查询
            var list = dbobj.items.Where(i => i.name == "abc");

            //遍历 或者 tolist 才会
            var reallist = await list.ToArrayAsync();
            //or
            //list.ForEachAsync()
            foreach (var l in reallist)
            {
                await context.Response.WriteAsync("item=" + l.ToString() + "\n");
            }

        }
    }
    class Item1
    {
        [Key]
        public int id
        {
            get;
            set;
        }
        public string name
        {
            get; set;
        }
        public int count
        {
            get; set;
        }
        public override string ToString()
        {
            return "id=" + id + " name=" + name + " count=" + count;
        }
    }
    class MyDbObj : DbContext
    {
        //这个Items 将被用做表名
        public DbSet<Item1> items { get; set; }
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseMySql("Server=localhost;Port=3306;Database=testdb; User=root;Password=;");
        }
    }

}
